package com.smart.service.sms;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.smart.common.cache.CacheService;
import com.smart.common.entities.constant.SmartConstant;
import com.smart.common.entities.enums.SmsScene;
import com.smart.common.exception.SmartException;
import com.smart.manager.system.repository.ConfigRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

/**
 * @author Administrator
 */
@Service
@RequiredArgsConstructor
@Log4j2
public class SmsService {

    private final CacheService cacheService;
    private final ConfigRepository configRepository;


    /**
     * 发送验证码
     *
     * @param scene       验证码发送场景
     * @param phoneNumber 电话号码
     */
    public void sendCaptchaCode(SmsScene scene, String phoneNumber) {
        String record = this.getCacheValue(scene, phoneNumber);
        Assert.isTrue(StrUtil.isBlank(record), "验证码已发送 请不要频繁操作");
        int captchaSize = 6;
        String captchaCode = RandomUtil.randomNumbers(captchaSize);
        JSONObject applyConfig = configRepository.readCache(SmartConstant.APPLY_SMS_CFG);

        boolean sendStatus;
        switch (applyConfig.getString("applyCode")) {
            //阿里云短信发送验证码
            case SmartConstant.ALIYUN_SMS_CFG:
                sendStatus = this.useAliyunSmsSend(phoneNumber, captchaCode);
                break;
            //腾讯云短信发送验证码
            case SmartConstant.TENCENT_SMS_CFG:
                JSONObject tencentConfig = configRepository.readCache(SmartConstant.TENCENT_SMS_CFG);
                int tplId = tencentConfig.getIntValue("captchaTemplateId");
                ArrayList<String> strings = new ArrayList<>();
                strings.add(captchaCode);
                sendStatus = this.useTencentSmsSend(tencentConfig, tplId, phoneNumber, strings);
                break;
            default:
                throw new SmartException("短信平台配置参数读取异常");


        }
        if (sendStatus) {
            putCache(scene, phoneNumber, captchaCode);
        }
    }




    /**
     * 发送验证码
     *
     * @param templateCode 模板短信ID
     * @param phoneNumber 电话号码
     */
    public void sendTemplateRemind(String phoneNumber, String templateCode) {

        JSONObject applyConfig = configRepository.readCache(SmartConstant.APPLY_SMS_CFG);

        switch (applyConfig.getString("applyCode")) {
            //阿里云短信发送验证码
            case SmartConstant.ALIYUN_SMS_CFG:
                 this.useAliyunPushTemplateMsg(phoneNumber, templateCode);
                break;
            //腾讯云短信发送验证码
            case SmartConstant.TENCENT_SMS_CFG:
                log.warn("腾讯云发送模板消息");
                break;
            default:
                throw new SmartException("短信平台配置参数读取异常");


        }
    }





























    /**
     *  检查验证码是否正确
     * @param scene
     * @param phoneNumber
     * @param captchaCode
     */
    public void checkCaptchaCode(SmsScene scene, String phoneNumber, String captchaCode) {
        String cacheValue = getCacheValue(scene, phoneNumber);
        Assert.notBlank(cacheValue, "验证码已过期");
        Assert.equals(captchaCode, cacheValue, "验证码错误");
        removeCache(scene,phoneNumber);
    }


    /**
     * 使用腾讯短信发送
     * 使用腾通讯短信发送
     *
     * @param config      配置
     * @param templateId  模板id
     * @param phoneNumber 电话号码
     * @param content     内容
     * @return boolean
     */

    private boolean useTencentSmsSend(JSONObject config, int templateId, String phoneNumber, ArrayList<String> content) {
        String nationCode = "86";
        int appId = config.getIntValue("appId");
        String appKey = config.getString("appKey");
        String sign = config.getString("sign");
        try {
            SmsSingleSender smsSingleSender = new SmsSingleSender(appId, appKey);
            SmsSingleSenderResult smsSingleSenderResult = smsSingleSender.sendWithParam(nationCode, phoneNumber, templateId, content, sign, "", "");
            return smsSingleSenderResult.result == 0;

        } catch (Exception e) {
            throw new SmartException("腾讯云短信发送失败:" + e.getMessage());

        }

    }










    /**
     * 使用阿里云发送短信
     *
     * @param phoneNumber 电话号码
     * @param captchaCode 验证码字符串
     * @return boolean
     */
    private boolean useAliyunSmsSend(String phoneNumber, String captchaCode) {

        JSONObject aliyunSmsConfig = configRepository.readCache(SmartConstant.ALIYUN_SMS_CFG);
        String regionId = aliyunSmsConfig.getString("regionId");
        String accessKeyId = aliyunSmsConfig.getString("accessKeyId");
        String secret = aliyunSmsConfig.getString("accessSecret");
        String signName = aliyunSmsConfig.getString("signName");
        String templateCode = aliyunSmsConfig.getString("captchaTemplateId");
        String templateParam = JSONObject.of("code", captchaCode).toJSONString();

        try {
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret);
            IAcsClient client = new DefaultAcsClient(profile);
            CommonRequest request = new CommonRequest();
            request.setSysMethod(MethodType.POST);
            request.setSysVersion("2017-05-25");
            request.setSysDomain("dysmsapi.aliyuncs.com");
            request.setSysAction("SendSms");
            request.putQueryParameter("RegionId", profile.getRegionId());
            request.putQueryParameter("PhoneNumbers", phoneNumber);
            request.putQueryParameter("SignName", signName);
            request.putQueryParameter("TemplateCode", templateCode);
            request.putQueryParameter("TemplateParam", templateParam);
            CommonResponse response = client.getCommonResponse(request);
            JSONObject callBack = JSONObject.parseObject(response.getData());
            String code = callBack.getString("Code").toUpperCase();
            if ("OK".equals(code)) {
                return  true ;
            }
            throw new RuntimeException("阿里云短信发送失败:" +  callBack.getString("Message"));
        } catch (Exception e) {
            throw new SmartException("阿里云短信发送失败:" + e.getMessage());

        }

    }











    /**
     * 使用阿里云发送模板短信
     *
     * @param phoneNumber 电话号码
     * @param templateCode 短信验证码模板
     * @return boolean
     */
    private boolean useAliyunPushTemplateMsg(String phoneNumber, String templateCode) {

        JSONObject aliyunSmsConfig = configRepository.readCache(SmartConstant.ALIYUN_SMS_CFG);
        String regionId = aliyunSmsConfig.getString("regionId");
        String accessKeyId = aliyunSmsConfig.getString("accessKeyId");
        String secret = aliyunSmsConfig.getString("accessSecret");
        String signName = aliyunSmsConfig.getString("signName");
        try {
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret);
            IAcsClient client = new DefaultAcsClient(profile);
            CommonRequest request = new CommonRequest();
            request.setSysMethod(MethodType.POST);
            request.setSysVersion("2017-05-25");
            request.setSysDomain("dysmsapi.aliyuncs.com");
            request.setSysAction("SendSms");
            request.putQueryParameter("RegionId", profile.getRegionId());
            request.putQueryParameter("PhoneNumbers", phoneNumber);
            request.putQueryParameter("SignName", signName);
            request.putQueryParameter("TemplateCode", templateCode);
            CommonResponse response = client.getCommonResponse(request);
            JSONObject callBack = JSONObject.parseObject(response.getData());
            String code = callBack.getString("Code").toUpperCase();
            if ("OK".equals(code)) {
                return  true ;
            }
            throw new RuntimeException("阿里云短信发送失败:" +  callBack.getString("Message"));
        } catch (Exception e) {
            throw new SmartException("阿里云短信发送失败:" + e.getMessage());

        }

    }













    /**
     * 查询验证码代码
     *
     * @param sceneCode   场景代码
     * @param phoneNumber 电话号码
     * @return {@code String}
     */
    public String getCacheValue(SmsScene sceneCode, String phoneNumber) {
        String cacheKey = getCacheKey(sceneCode, phoneNumber);
        return cacheService.getSmsCaptchaCache().get(cacheKey);
    }


    /**
     * 获取验证码缓存KEY
     *
     * @param sceneCode
     * @param phoneNumber
     * @return {@code String}
     */
    private String getCacheKey(SmsScene sceneCode, String phoneNumber) {
        return sceneCode.name().concat(":").concat(phoneNumber);
    }


    /**
     * 写入短信验证码缓存
     *
     * @param sceneCode
     * @param phoneNumber
     * @param content
     */
    private void putCache(SmsScene sceneCode, String phoneNumber, String content) {
        String cacheKey = getCacheKey(sceneCode, phoneNumber);
        cacheService.getSmsCaptchaCache().put(cacheKey, content);

    }


    /**
     * 获取验证码缓存KEY
     *
     * @param sceneCode
     * @param phoneNumber
     * @return {@code String}
     */
    private void removeCache(SmsScene sceneCode, String phoneNumber) {
        String cacheKey = getCacheKey(sceneCode, phoneNumber);
        cacheService.getSmsCaptchaCache().remove(cacheKey);

    }


}